# -*- coding: utf-8 -*-

import sys
import urllib
import urllib2

def get_user_token(username, password):
    """获取token。
    
    根据用户和密码，到keystone处获取token。

    参数：
        username: 用户名。 
        password: 密码。

    返回值：
        返回获取的token，字符串格式。
    """
    url = 'http://controller:35357/v3/auth/tokens'
    body = ('{"auth": {"scope": {"project": {"domain": {"name": "Default"}, "name": "%s"}},'
        '"identity": {"password": {"user": {"domain": {"name": "Default"}, "password": "%s", "name": "%s"}},'
        '"methods": ["password"]}}}'%(username, password, username))
    headers = {'Content-Type': 'application/json'}
    req = urllib2.Request(url, body, headers)
    response = urllib2.urlopen(req)
    return response.info()['X-Subject-Token']

def get_server_virtual(compute):
    """获取物理主机上的所有虚拟机id以及其状态

    根据物理主机名称，获取该物理主机上所有的虚拟机id及其运行状态

    参数：
        compute: 物理主机名称

    返回值：
        虚拟机列表,列表中元素为字典,字典存储虚拟机的id和状态信息
        例如:

        [{'status': 'SHUTOFF', 'id': 'b964fafb-47f8-4638-b8af-67347009edad'},
        {'status': 'ACTIVE', 'id': '3a7d946d-e7e2-4906-9996-60803a536d83'}]        
    """
    token = get_user_token('admin', 'bjtungirc')
    url = 'http://controller:8774/v2.1/servers/detail?host=%s'%compute
    headers = {"OpenStack-API-Version": "compute 2.53", "User-Agent": "python-novaclient"}
    headers.update({"Accept": "application/json", "X-OpenStack-Nova-API-Version": 2.53})
    headers.update({"X-Auth-Token": token})
    req = urllib2.Request(url=url, headers=headers)
    response = urllib2.urlopen(req)
    #eval()函数将字符串装换成字典，但是对null和false无法处理，所以提前赋值(下同)
    null = "null"
    false = "false"
    response = eval(response.read())
    virtuals = response["servers"]
    virtual_list = []
    for virtual in virtuals:
        virtual_list.append({"id": virtual["id"], "status": virtual["status"]})
    return virtual_list
def main():
    if len(sys.argv) != 2:
        print "Input ERROR"
        return
    result = get_server_virtual(sys.argv[1])
    print result
if __name__ == "__main__":
    main()

